﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CanDoo;
using CanDoo.Core;
using CanDoo.Core.Data;
using CanDoo.Data;
using CanDoo.Extensions;
using CanDoo.Oil.Core.Contracts;
using CanDoo.Oil.Core.DTOs;
using CanDoo.Oil.Core.Models;
using System.Threading.Tasks;

namespace CanDoo.Oil.Core.Services
{
    /// <summary>
    /// 业务实现——油品序列号
    /// </summary>
    public class OilSerialNumService : CanDoo.Data.Entity.Services.ServiceBase<OilSerialNum>, IOilSerialNumContract
    {
        public IOilSalesSerialNumContract OilSalesSerialNumContract { get; set; }
        public ICustomerContract CustomerContract { get; set; }
        public IAPIOperateLogContract APIOperateLogContract { get; set; }
        public IChangeOilDrumContract ChangeOilDrumContract { get; set; }
        public OilSerialNumService()
        {
        
        }

        /// <summary>
        /// 批量从销售退货单序列号中删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public OperationResult DeleteFromSellOutBackByIds(long[] ids)
        {
            OperationResult result = OperationResult.NoChanged;
            using (var scope = DbScopeFactory.Create())
            {
                foreach (var m in ids)
                    DeleteFromSellOutBack(m);
                return scope.SaveChanges() > 0 ? OperationResult.Success : OperationResult.NoChanged;
            }
        }

        /// <summary>
        /// 从销售退货单序列号中删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public OperationResult DeleteFromSellOutBack(long id)
        {
            OperationResult result = OperationResult.NoChanged;
            using (var scope = DbScopeFactory.Create())
            {
                var mEntity = GetById(id);
                if (mEntity != null)
                {
                    if (mEntity.Status != OilSerialStatus.WaitBack)
                    {
                        throw new Exception("数据[" + id + "]状态不正确，不允许删除");
                    }
                    else
                    {
                        mEntity.Status = OilSerialStatus.PassOut;
                        mEntity.OutSellBackId = null;
                        return UpdateEntity(mEntity);
                    }
                }
                else
                {
                    throw new Exception("数据[" + id + "]不存在，可能已删除");
                }
            }
        }


        /// <summary>
        /// 批量从销售出库单序列号中删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public OperationResult DeleteFromSellOutStoreByIds(long[] ids)
        {
            OperationResult result = OperationResult.NoChanged;
            using (var scope = DbScopeFactory.Create())
            {
                foreach (var m in ids)
                    DeleteFromSellOutStore(m);
                return scope.SaveChanges() > 0 ? OperationResult.Success : OperationResult.NoChanged;
            }
        }

        /// <summary>
        /// 从销售出库单序列号中删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public OperationResult DeleteFromSellOutStore(long id)
        {
            OperationResult result = OperationResult.NoChanged;
            using (var scope = DbScopeFactory.Create())
            {
                var mEntity = GetById(id);
                if (mEntity != null)
                {
                    if (mEntity.Status != OilSerialStatus.WaitOut)
                    {
                        throw new Exception("数据[" + id + "]状态不正确，不允许删除");
                    }
                    else
                    {
                        if(mEntity.OutSellBackId!=null)
                            mEntity.Status = OilSerialStatus.Back;
                        else
                            mEntity.Status = OilSerialStatus.PassIn;
                        mEntity.OutStoreId = null;
                        mEntity.OutStoreTypeId = null;
                        return UpdateEntity(mEntity);
                    }
                }
                else
                {
                    throw new Exception("数据[" + id + "]不存在，可能已删除");
                }
            }
        }



        /// <summary>
        /// 批量从采购退货单序列号中删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public OperationResult DeleteFromInBuyBackByIds(long[] ids)
        {
            OperationResult result = OperationResult.NoChanged;
            using (var scope = DbScopeFactory.Create())
            {
                foreach (var m in ids)
                    DeleteFromInBuyBack(m);
                return scope.SaveChanges() > 0 ? OperationResult.Success : OperationResult.NoChanged;
            }
        }

        /// <summary>
        /// 从采购退货单序列号中删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public OperationResult DeleteFromInBuyBack(long id)
        {
            OperationResult result = OperationResult.NoChanged;
            using (var scope = DbScopeFactory.Create())
            {
                var mEntity = GetById(id);
                if (mEntity != null)
                {
                    if (mEntity.Status != OilSerialStatus.WaitBuyBack)
                    {
                        throw new Exception("数据[" + id + "]状态不正确，不允许删除");
                    }
                    else
                    {
                        mEntity.Status = OilSerialStatus.PassIn;
                        mEntity.InBuyBackId = null;
                        return UpdateEntity(mEntity);
                    }
                }
                else
                {
                    throw new Exception("数据[" + id + "]不存在，可能已删除");
                }
            }
        }

        /// <summary>
        /// 1.1.10更换油桶状态上报 向后台上报油桶更换结果
        /// </summary>
        /// <param name="changeOilDrumInfo"></param>
        /// <returns></returns>
        public async Task<OperationResult> ChangeOilDrumInfo(ChangeOilDrumInfo changeOilDrumInfo)
        {
            using (var scope = DbScopeFactory.Create())
            {
                OperationResult result = OperationResult.NoChanged;

                var customer = await CustomerContract.SingleOrDefaultAsync(p => p.CardNo == changeOilDrumInfo.storeNo);
                if (customer == null)
                {
                    result.ResultType = OperationResultType.ValidError;
                    result.Message = "客户不存在";
                    return result;
                }


                var oilSalesSerialNum = await OilSalesSerialNumContract.SingleOrDefaultAsync(p => p.TerminalNum == changeOilDrumInfo.terminalNo);
                if (customer == null)
                {
                    result.ResultType = OperationResultType.ValidError;
                    result.Message = "终端号不存在";
                    return result;
                }


                var entity = await SingleOrDefaultAsync(p => p.SerialNumber.ToUpper() == changeOilDrumInfo.tid.ToUpper() || p.SerialNumber.ToUpper() == changeOilDrumInfo.epc.ToUpper());
                if (entity == null)
                {
                    result.ResultType = OperationResultType.ValidError;
                    result.Message = "RFID不存在";
                    return result;
                }

#if TEST

#else
                if (entity.Status != OilSerialStatus.RequestChange)
                {
                    result.ResultType = OperationResultType.ValidError;
                    var status = entity.Status;
                    result.Message = "此RFID不处于申请换油桶操作，处于"+ status.ToDescription();

                    changeOilDrumInfo.epc = entity.SerialNumber;
                    changeOilDrumInfo.tid = "";
                    //changeOilDrumInfo.storeNo = entity.Customer.CardNo;
                    //changeOilDrumInfo.terminalNo = entity.OilSalesSerialNum.TerminalNum;
                    //changeOilDrumInfo.oilPort = entity.OilPort;
                    changeOilDrumInfo.type = 0;
                    changeOilDrumInfo.operation = "";
                    changeOilDrumInfo.operationTime = DateTime.MinValue;
                    changeOilDrumInfo.status = entity.Status;

                    return result;
                }

                else if (entity.Status == OilSerialStatus.OnSale)
                {
                    result.ResultType = OperationResultType.ValidError;
                    result.Message = "此RFID正在使用,请根据返回信息检查是否重复操作";

                    changeOilDrumInfo.epc = entity.SerialNumber;
                    changeOilDrumInfo.tid = "";
                    changeOilDrumInfo.storeNo = entity.Customer.CardNo;
                    changeOilDrumInfo.terminalNo = entity.OilSalesSerialNum.TerminalNum;
                    changeOilDrumInfo.oilPort = entity.OilPort;
                    changeOilDrumInfo.type = 0;
                    changeOilDrumInfo.operation = "";
                    changeOilDrumInfo.operationTime = DateTime.MinValue;
                    changeOilDrumInfo.status = entity.Status;

                    return result;
                }

                if(entity.OilSalesSerialNumId != oilSalesSerialNum.Id || entity.OilPort != changeOilDrumInfo.oilPort)
                {
                    result.ResultType = OperationResultType.ValidError;
                    result.Message = "此油上机油口与终端与申请的不一致";

                    changeOilDrumInfo.epc = entity.SerialNumber;
                    changeOilDrumInfo.tid = "";
                    changeOilDrumInfo.storeNo = entity.Customer.CardNo;
                    changeOilDrumInfo.terminalNo = entity.OilSalesSerialNum.TerminalNum;
                    changeOilDrumInfo.oilPort = entity.OilPort;
                    changeOilDrumInfo.type = 0;
                    changeOilDrumInfo.operation = "";
                    changeOilDrumInfo.operationTime = DateTime.MinValue;
                    changeOilDrumInfo.status = entity.Status;

                    return result;
                }
#endif

                entity.UpTime = System.DateTime.Now;
                entity.Status = OilSerialStatus.OnSale;
                entity.CustomerId = customer.Id;

                Update(entity);
#if TEST

#else
                var olds = TrackEntities.Where(p => p.OilSalesSerialNumId == oilSalesSerialNum.Id && p.OilPort == changeOilDrumInfo.oilPort && p.Status == OilSerialStatus.OnSale).ToList();
                foreach (var old in olds)
                {
                    old.Status = OilSerialStatus.SaleOut;
                    old.DownTime = System.DateTime.Now;
                    Update(old);
                }
#endif

                var mEntity = new ChangeOilDrum();
                mEntity.Id = IdMaker.NewId();
                mEntity.Name = "终端[" + oilSalesSerialNum.TerminalNum + "]" + changeOilDrumInfo.oilPort + "号油口更换油桶";
                mEntity.OilSalesSerialNumId = oilSalesSerialNum.Id;
                mEntity.OilPort = changeOilDrumInfo.oilPort;
                mEntity.OilSerialNumId = entity.Id;
                mEntity.OperateTime = changeOilDrumInfo.operationTime;
                ChangeOilDrumContract.AddEntity(mEntity);

#region APIOperateLog
                //var mEntity = new APIOperateLog();
                //mEntity.Id = IdMaker.NewId();
                //mEntity.Name = "终端[" + oilSalesSerialNum.TerminalNum + "]" + changeOilDrumInfo.oilPort + "号油口更换油桶";
                //mEntity.OperateType = 11;
                //mEntity.OilSalerNo = oilSalesSerialNum.TerminalNum;
                //mEntity.OilPort = changeOilDrumInfo.oilPort;
                //mEntity.BatchNo = "";
                //mEntity.OpreateTime = changeOilDrumInfo.operationTime;
                //if (mEntity.OpreateTime == DateTime.MinValue)
                //    mEntity.OpreateTime = null;

                //mEntity.OilOutPut = 0;
                //mEntity.Before = 20.0;
                //mEntity.Last = 20.0;
                //mEntity.Price = 0.0;
                //mEntity.Money = 0.0;
                //mEntity.UpdateTime = null;
                //if (mEntity.UpdateTime == DateTime.MinValue)
                //    mEntity.UpdateTime = null;
                //mEntity.Token = "";
                //mEntity.Status = 1;// changeOilDrumInfo.status;
                //mEntity.OilSalesSerialNumId = oilSalesSerialNum.Id;
                //mEntity.OilSerialNumId = entity.Id;
                //mEntity.Operater = "--";
                //mEntity.LinkEntityId = null;
                //mEntity.CustomerId = null;
                //APIOperateLogContract.AddEntity(mEntity); 
#endregion

                result = scope.SaveChanges() > 0 ? OperationResult.Success : OperationResult.NoChanged;
                return result;


                //TODO : 这里还有洗油桶操作的  
                //TODO : 如果失败 我要做什么
                //TODO : 暂时先提交
            }
        }

        public async Task<OperationResult> ChangeOilDrumReq(OilDrumReqInfo oilDrumReqInfo)
        {
            using (var scope = DbScopeFactory.Create())
            {
                OperationResult result = OperationResult.NoChanged;

                var customer = await CustomerContract.SingleOrDefaultAsync(p => p.CardNo == oilDrumReqInfo.storeNo);
                if (customer == null)
                {
                    result.ResultType = OperationResultType.ValidError;
                    result.Message = "客户不存在";
                    return result;
                }


                OilSalesSerialNum oilSalesSerialNum = await OilSalesSerialNumContract.SingleOrDefaultAsync(p => p.TerminalNum == oilDrumReqInfo.terminalNo);
                if (oilSalesSerialNum == null)
                {
                    result.ResultType = OperationResultType.ValidError;
                    result.Message = "终端号不存在";
                }

                var entity = await SingleOrDefaultAsync(p => p.SerialNumber.ToUpper() == oilDrumReqInfo.epc.ToUpper() || p.SerialNumber.ToUpper() == oilDrumReqInfo.tid.ToUpper());
                if (entity == null)
                {
#if TEST
                    entity = new OilSerialNum();
                    entity.Id = IdMaker.NewId();

                    entity.InStoreTypeId = 2558565948588032;
                    entity.InStoreId = 40323894527135744;

                    entity.OutStoreTypeId = 2559103184404480;
                    entity.OutStoreId = 40324700055801856;


                    entity.WarehouseId = 2665306002554880;
                    if (oilDrumReqInfo.oilPort == 1)
                        entity.ProductId = 2975564981862300;
                    else if (oilDrumReqInfo.oilPort == 2)
                        entity.ProductId = 2975270021627904;
                    else if (oilDrumReqInfo.oilPort == 3)
                        entity.ProductId = 2975270021627900;
                    else
                        entity.ProductId = 2975564981862300;
                    entity.SerialNumber = oilDrumReqInfo.tid;
                    entity.OilPort = 0;
                    entity.LastOil = 25000;
                    entity.Status = OilSerialStatus.PassOut;
                    entity.CreatorUserId = "162742199648256";
                    entity.Name = "程序自动添加";
                    entity.CreatedTime = System.DateTime.Now;
                    AddEntity(entity);
#else
                    result.ResultType = OperationResultType.ValidError;
                    result.Message = "epc 或 tid 都不存在";
                    return result;

#endif
                }

                if (entity.Status != OilSerialStatus.PassOut)
                {
                    result.ResultType = OperationResultType.ValidError;
                    var status = entity.Status;
                    result.Message = "此RFID不处于审核出库状态,处于" + status.ToDescription();
                    return result;
                }

                else if (entity.Status == OilSerialStatus.OnSale)
                {
                    result.ResultType = OperationResultType.ValidError;
                    result.Message = "此RFID正在使用,请根据返回信息检查是否重复操作";
                    //{  "epc": "2234576",  "tid": "1",  "storeNo": "123123",  "terminalNo": "1",  "oilPort": 1}
                    oilDrumReqInfo.epc = entity.SerialNumber;
                    oilDrumReqInfo.storeNo = entity.Customer.CardNo;
                    oilDrumReqInfo.terminalNo = entity.OilSalesSerialNum.TerminalNum;
                    oilDrumReqInfo.oilPort = entity.OilPort;
                    return result;
                }

                entity.OilSalesSerialNumId = oilSalesSerialNum.Id ;
                entity.OilPort = oilDrumReqInfo.oilPort;

                entity.CustomerId = customer.Id;
                entity.Status = OilSerialStatus.RequestChange;

                Update(entity);

#region 记录API操作日志
                var mEntity = new APIOperateLog();
                mEntity.Id = IdMaker.NewId();
                mEntity.Name = "终端[" + oilSalesSerialNum.TerminalNum + "]" + oilDrumReqInfo.oilPort + "号油口申请更换油桶";
                mEntity.OperateType = 10;

                mEntity.OilSalerNo = oilSalesSerialNum.TerminalNum;
                mEntity.OilPort = oilDrumReqInfo.oilPort;
                mEntity.BatchNo = "";
                mEntity.OpreateTime = DateTime.Now;
               
                mEntity.OilOutPut = 0;
                mEntity.Before = 20.0;
                mEntity.Last = 20.0;
                mEntity.Price = 0.0;
                mEntity.Money = 0.0;
                mEntity.UpdateTime = null;
                if (mEntity.UpdateTime == DateTime.MinValue)
                    mEntity.UpdateTime = null;
                mEntity.Token = "";
                mEntity.Status = 1;
                mEntity.OilSalesSerialNumId = oilSalesSerialNum.Id;
                mEntity.OilSerialNumId = entity.Id;
                mEntity.Operater = "--";
                mEntity.LinkEntityId = null;
                mEntity.CustomerId = null;
                APIOperateLogContract.AddEntity(mEntity);
#endregion
                scope.SaveChanges();
                result = OperationResult.Success;
                return result;
            }
        }
    }
}
